/*
 * Copyright (c) 2011 Imre Fazekas.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 *   Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 *   Neither the name of the Wit-In Comp Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.acme.creditblue;

import com.acme.creditblue.util.TransferRequest;
import com.vii.brillien.core.component.SuperFlow;
import com.vii.brillien.kernel.BrillienException;
import com.vii.brillien.kernel.annotations.Activate;
import com.vii.brillien.kernel.annotations.Indispensable;
import com.vii.brillien.kernel.annotations.PresenceService;
import com.vii.brillien.kernel.annotations.lifecycle.Sparkle;
import com.vii.streamline.annotation.P;

import java.util.HashMap;

/**
 * This class represents a money transfer flow started by a client
 */
@PresenceService( logLevel = PresenceService.INFO, messageExpiration = 2000 )
@Indispensable
@Sparkle
public class Transfer extends SuperFlow {

    @Override
    protected void expandStateSpace(HashMap space) {
        space.put( "time", System.currentTimeMillis() );
    }

    @Override
    protected void recollectStateSpace( HashMap space ){
        System.out.println("Time::" + space.get("time") );
    }

    @Activate( timeout = 8000 )
    public String startTransaction( @P(name="req") TransferRequest req ) throws BrillienException {
        System.out.println(">>" + req);

        try {
            if( sendGet( "customerdataprovider", "validateCustomerData", req.getSenderName(), req.getSenderAccountNumber() ).<Boolean>acquireResponse( ) ){
                sendGet( "cachier", "deposit", req.getSenderName(), req.getSenderAccountNumber(), req.getAmount(), req.getCurrency() );

                if( sendGet( "customerdataprovider", "validateCustomerData", req.getRecipientName(), req.getRecipientAccountNumber() ).<Boolean>acquireResponse( ) ){
                    sendGet( "cachier", "load", req.getRecipientName(), req.getRecipientAccountNumber(), -req.getAmount(), req.getCurrency() );
                    sendGet( "cachier", "load", req.getSenderName(), req.getSenderAccountNumber(), req.getAmount(), req.getCurrency() );
                    return "Successful transfer.";
                }
                else{
                    sendGet( "cachier", "load", req.getSenderName(), req.getSenderAccountNumber(), req.getAmount(), req.getCurrency() );
                    sendAGet( "exchanger", "externalize", "externalized", req.getSenderName(), req.getRecipientName(), req.getRecipientAccountNumber(), req.getAmount(), req.getCurrency() );
                }                
            }
            else
                return "Invalid client data!";
        } catch (BrillienException e) {
            throw new BrillienException("Cannot handle request", e);
        }

        return null; 
    }

    public String externalized( String message ){
        System.out.println("Externalized:" + message);                  
        return message + " transfer";
    }

    @Override
    public void aspirationTimeIsUp() {
        System.out.println("Working too hard...");
    }

}
